#!/usr/bin/env python


import jplur
import jplur.objects as objects
import jplur.console as console
import jplur.widgets as widgets
import jplur.colors as colors

from math import floor, sqrt, pow

tcod = console.Console(80, 60, "GridFolk")



import sys
from time import sleep
from sys import stdin, exit

from PodSixNet.Connection import connection, ConnectionListener

jplur.QUIT = 0

############ widgets #################
message = widgets.messagebox(tcod.libtcod, tcod, 1,35, 79, 23, "black", "white")
mapbox = widgets.mapbox(tcod.libtcod, tcod, 1,1, 58, 58, "dark_blue", "white")
textentry = widgets.messagebox(tcod.libtcod, tcod, 1,58, 79, 1, "black", "orange")
status = widgets.messagebox(tcod.libtcod, tcod, 26,1, 53, 33, "dark_grey", "white")
health = widgets.percentage_bar(tcod.libtcod, 1,26,15,1,"")
exp = widgets.percentage_bar(tcod.libtcod, 1,29,15,1,"",color="magenta", back_color="dark_grey")

class Map:
	def __init__(self, dimension, cell_size, z_levels):
		self.dimension = dimension
		self.cell_size = cell_size
		self.z_levels = z_levels
		self.data = []
		self.player_location = [1,1,1]
		
		self.entities = {}
		self.objects = {}
		
		for z in range(z_levels):
			self.data.append([])
			for x in range(self.dimension[0]):
				self.data[z].append([])
				for y in range(self.dimension[1]):
					self.data[z][x].append(0)
		
	def key(self, point):
		cell_size = self.cell_size
		return (
			int(point[0]), #z 
			int((floor(point[1]/cell_size))),
			int((floor(point[2]/cell_size)))
		)
	def get_sector(self, sector): 
	
		z =  sector[0]
		x = sector[1]
		y = sector[2]
		x_slice = self.data[z][ x*self.cell_size : x*self.cell_size+self.cell_size ]
		y_slice = []
		for entry in x_slice:
			y_slice.append( entry[y*self.cell_size : y*self.cell_size+self.cell_size ] )
			
		return y_slice
		
	def display_bounds(self):
		key = self.key(self.player_location)
		bounds = [(key[2]-1)*self.cell_size, (key[1]-1)*self.cell_size, (key[2]-1)*self.cell_size+self.cell_size*3, (key[1]-1)*self.cell_size+self.cell_size*3] #!!!!!!!!!!!!!! ?????

		return bounds
	
	def total_player_view(self):
		map = []
		key = self.key(self.player_location)
		for x in range(3):
			for y in range(3):
				map.append( self.get_sector( [key[0], key[1]+(x-1), key[2]+(y-1)] ) )
		return map
		
	def update(self, data):
		
		for chunk in data: #the chunk

			key = chunk[0]
			cell = chunk[1]
			i = 0
			
			for x in range(self.cell_size):
				for y in range(self.cell_size):
					try:
						self.data[key[0]][key[1]*self.cell_size+x][key[2]*self.cell_size+y] = cell[x][y]
					except:
						pass
		
		self.display_bounds()

		
	def dump_map(self, level):
		#strip this for release, has PIL 
		im = Image.new( "RGB", (self.dimension[0], self.dimension[1] ) )
		tile_colors = colors.tiles()
		y = 0
		for entry in self.data[level]:
			x = 0
			for spot in entry:
				color = (0,0,0)
				sample = self.data[level][y][x]
				if sample in tile_colors:
					color = tuple(colors.hextorgb( tile_colors[sample][1] ))
				
				im.putpixel( (x, y), color)
				x += 1
			y += 1

		im.save('dump-level-'+str(level)+'.png')

	def entity(self, packet):
		for data in packet:
			self.entities[data[0]] = [data[1], data[2], data[3]] #symbol color location
			
	def remove(self, id):
		try:
			del self.entities[id]
		except:
			pass
			
	def single(self, loc, tile):
		print "single!"
		self.data[loc[0]][loc[1]][loc[2]] = tile
		

class Client(ConnectionListener):
	def __init__(self, host, port):
		
		self.Connect((host, port))
		self.color_d = []
		self.terrain_d = []

		self.enterline = 1
		
		jplur.highlite = -1
		jplur.hp = [0,0]
		jplur.exp = [0,0]
		

		
	def Push(self, data):
		action = "message"
		connection.Send({"action": action, "data": data})

	def Command(self, data):
		action = "C"
		connection.Send({"action": action, "data": data})
		
	def Loop(self):
		connection.Pump()
		self.Pump()
		
	
	#######################################
	### Network event/message callbacks ###
	#######################################
	
	def Network_players(self, data):
		message.update( "* players: " + ", ".join([p for p in data['players']]) )
	
	def Network_message(self, data):
		message.update(data['data'])

	def Network_getinput(self, data):
		self.enterline = 1

	def Network_clearmessage(self, data):
		message.lines = []

	def Network_colors(self, data):
		tcod.color_d = data['colors']
		
	def Network_menu(self, data):
		status.update(data['data'])
		
	def Network_single(self, packet):
		jplur.map.single(packet['loc'], packet['tile'])
		

	
	
	# built in stuff

	def Network_connected(self, data):
		print data

	
	def Network_error(self, data):
		message.update( 'error:', data['error'][1] )
		connection.Close()
	
	def Network_disconnected(self, data):
		message.update( 'Server disconnected' )
		exit()
		
	def Network_sync_maps(self, packet):
		data = packet['data']
		jplur.map = Map(data[0], data[1], data[2])
		
	def Network_p(self, packet): #player location
		jplur.map.player_location = packet['data']
		print "location set to: ", packet['data']
		self.player_location = packet['data']

	def Network_fullview(self, data):
		print data['data']
		mapbox.update(data['data'])
		
	def Network_m(self, packet): #entity moved

		jplur.map.entity(packet['data'])
		
	def Network_line_entry(self, packet):
		self.enterline = packet['data'] 
		
	def Network_menu_clear(self, packet=0):
		status.lines = []
		
	def Network_highlite(self, packet):
		jplur.highlite = packet['data']
		
	def Network_hp(self,packet):
		jplur.hp = packet['data']
		
	def Network_remove(self, packet):
		jplur.map.remove(packet['data'])
		
	def Network_quit(self, packet):
		jplur.QUIT = 1
		
	def Network_exp(self,packet):
		jplur.exp = packet['data']





#Connect to Server
addr = open("server-port.txt", "r")
host = str( addr.readline()[:-1])
port = int( addr.readline() )
print host, port
#host, port = ['localhost', 5071]
c = Client(host, int(port))


inp = ""
while not (tcod.libtcod.console_is_window_closed() or jplur.QUIT == 1):

	c.Loop()
       
	message.draw()
	mapbox.draw()
	status.draw()
	health.text = "HP:"+str(jplur.hp[0])+"/"+str(jplur.hp[1])
	health.draw(jplur.hp[0],jplur.hp[1])
	exp.text = "EXP:"+str(jplur.exp[0])+"/"+str(jplur.exp[1])
	exp.draw(jplur.exp[0],jplur.exp[1])
	keys = tcod.keycheck(False)
	if c.enterline == 1:
		imp = ""
		textentry.color = "white"
		if keys[0] == 4:
				
			c.Push(inp)
			
			inp = ""
			c.enterline = 0
			textentry.color = "dark_grey"
		elif keys[0] == 2:
			inp = inp[:-1]
		elif keys != (0,0):
			inp += chr(keys[1])
		textentry.update([">"+inp])
	else:
		textentry.color = "dark_grey"
		if keys[0] != 0:
			if keys[1] == 9:
				c.enterline = 1
			else:
				c.Command( keys[1] )
		
	textentry.draw()
	tcod.libtcod.console_flush()



